package com.hmkj.core.api.jbppay;


import com.alibaba.fastjson.JSON;
import com.hmkj.common.utils.HttpClientUtils;
import com.hmkj.common.utils.MD5Utils;
import com.hmkj.common.utils.OrderNoUtils;
import com.hmkj.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 聚宝盆支付接口工具类
 *
 * @author eproo
 * @create 2018-04-25 19:26
 */
@Slf4j
public class JbpPayUtils {

    /**
     * 银行卡转账充值
     *
     * @param webUrl
     * @param userId
     * @param type
     * @param alipayName
     * @param transAmt
     * @param bankId
     * @return
     * @throws Exception
     */
    public static Map<String, Object> deposit(String webUrl, Integer userId, Integer type, String alipayName, BigDecimal transAmt, Integer bankId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        String url = JbpPayConfig.DEPOSIT_URL;//银行卡转账充值提交地址
        String company_id = JbpPayConfig.COMPANY_ID;//商户ID：支付平台提供给商户的数字编码
        String bank_id, note_model, note;
        if (type == 1) {//银行卡转账
            bank_id = bankId.toString();//银行ID：用户发起充值的银行ID
            note_model = "2";//订单匹配模式：1商户自传附言2支付平台附言 3 支付平台金额 4 商户金额
            note = "";//附言：如果note_model为1，note不能为空
        } else {//支付宝转账
            bank_id = "30";
            note_model = "1";//订单匹配模式：1商户自传附言2支付平台附言 3 支付平台金额 4 商户金额
            note = alipayName;//附言：如果note_model为1，note不能为空
        }
        String estimated_payment_bank = bank_id;//用户预计使用银行：与bank_id一致
        String amount = String.valueOf(transAmt.setScale(2, BigDecimal.ROUND_HALF_UP));//充值金额
        String company_order_num = OrderNoUtils.getJbpRechargeOrderNo();//商户订单号
        String company_user = userId.toString();//用户ID
        String deposit_mode = "1";//充值渠道：1（网银转账）
        String group_id = "0";//群组ID：支付平台自用参数，建议商户默认0
        String web_url = webUrl + JbpPayConfig.NOTIFY_URL;//商户网址
        String memo = "";//备用字段


        String terminal = "1";//使用终端：1电脑端2手机端3平板9其他
        params.put("company_id", company_id);
        params.put("bank_id", bank_id);
        params.put("account", amount);
        params.put("company_order_num", company_order_num);
        params.put("company_user", company_user);
        params.put("estimated_payment_bank", estimated_payment_bank);
        params.put("deposit_mode", deposit_mode);
        params.put("group_id", group_id);
        params.put("web_url", web_url);
        params.put("memo", memo);
        params.put("note", note);
        params.put("note_model", note_model);
        params.put("terminal", terminal);
        String paramStr = company_id + bank_id + amount + company_order_num + company_user + estimated_payment_bank + deposit_mode + group_id + web_url + memo + note + note_model;
        params.put("key", signDataStr(paramStr));
        log.info("聚宝盆支付参数：{}", JSON.toJSONString(params));

        String result = HttpClientUtils.httpPost(url, params);
        log.info("聚宝盆支付返回结果：" + result);
        return (Map) JSON.parse(result);
    }

//    /**
//     * 电子钱包充值到银行卡
//     * @param userId
//     * @param transAmt
//     * @param bankId
//     * @param webUrl
//     * @param transNote
//     * @return
//     * @throws Exception
//     */
//    public static Map<String, String> elecWallet(Integer userId, BigDecimal transAmt,Integer bankId,String webUrl,String transNote) throws Exception {
//        Map<String, Object> params = new HashMap<>();
//        String url = ConfigUtils.getProperty("jbp_deposit_url");//银行卡转账充值提交地址
//        String company_id = ConfigUtils.getProperty("jbp_company_id");//商户ID：支付平台提供给商户的数字编码
//        String bank_id = bankId.toString();//银行ID：用户发起充值的银行ID
//        String account = String.valueOf(transAmt.setScale(2, BigDecimal.ROUND_HALF_UP));//充值金额
//        String company_order_num = OrderNoUtils.getJbpRechargeOrderNo();//商户订单号
//        String company_user = userId.toString();//用户ID
//        String estimated_payment_bank = bank_id;//用户预计使用银行：与bank_id一致
//        String deposit_mode = "1";//充值渠道：1（网银转账）
//        String group_id = "0";//群组ID：支付平台自用参数，建议商户默认0
//        String web_url = webUrl;//商户网址
//        String memo = "";//备用字段
//        String note = transNote;//附言：如果note_model为1，note不能为空
//        String note_model = "1";//订单匹配模式：1商户自传附言2支付平台附言 3 支付平台金额 4 商户金额
//        String terminal = "1";//使用终端：1电脑端2手机端3平板9其他
//        params.put("company_id", company_id);
//        params.put("bank_id", bank_id);
//        params.put("account", account);
//        params.put("company_order_num", company_order_num);
//        params.put("company_user", company_user);
//        params.put("estimated_payment_bank", estimated_payment_bank);
//        params.put("deposit_mode", deposit_mode);
//        params.put("group_id", group_id);
//        params.put("web_url", web_url);
//        params.put("memo", memo);
//        params.put("note", note);
//        params.put("note_model", note_model);
//        params.put("terminal", terminal);
//        String paramStr = company_id + bank_id + account + company_order_num + company_user + estimated_payment_bank + deposit_mode + group_id + web_url + memo + note + note_model;
//        params.put("key", signDataStr(paramStr));
//
//        System.out.println("参数列表：" + "company_id=" + company_id + "\n"
//                + "bank_id=" + bank_id + "\n"
//                + "account=" + account + "\n"
//                +"company_order_num=" + company_order_num + "\n"
//                +"company_user=" + company_user +"\n"
//                +"estimated_payment_bank="+estimated_payment_bank+"\n"
//                +"deposit_mode="+deposit_mode+"\n"
//                +"group_id="+group_id+"\n"
//                +"web_url="+web_url+"\n"
//                +"memo="+memo+"\n"
//                +"note="+note+"\n"
//                +"note_model="+note_model+"\n"
//                +"terminal="+terminal+"\n"
//                +"key="+signDataStr(paramStr)+"\n"
//        );
//
//        String result = HttpClientUtils.httpPost(url, params);
//        System.out.println("聚宝盆支付返回结果：" + result);
//        return new HashMap<>();
//    }

    /**
     * 提现
     *
     * @param userId
     * @param transAmt
     * @param bankId
     * @param cardName
     * @param cardNum
     * @param bankAddress
     * @return
     * @throws Exception
     */
    public static Map<String, Object> withdrawal(Integer userId, BigDecimal transAmt, Integer bankId, String cardName, String cardNum, String bankAddress, String orderNo) throws Exception {
        Map<String, Object> params = new HashMap<>();
        String url = JbpPayConfig.WITHDRAWAL_URL;//提现提交地址
        String company_id = JbpPayConfig.COMPANY_ID;//商户ID：支付平台提供给商户的数字编码
        String bank_id = bankId.toString();//银行ID：用户发起充值的银行ID
        String amount = String.valueOf(transAmt.setScale(2, BigDecimal.ROUND_HALF_UP));//充值金额
        String company_order_num = orderNo;//商户订单号
        String company_user = userId.toString();//用户ID
        String card_name = cardName;//用户提现银行卡姓名
        String card_num = cardNum;//用户的提现银行卡卡号
        String issue_bank_name = outIdToName(bankId);//开户行名称
        String issue_bank_address = bankAddress;//开户行地址
        String memo = "";//备用字段
        params.put("company_id", company_id);
        params.put("bank_id", bank_id);
        params.put("account", amount);
        params.put("company_order_num", company_order_num);
        params.put("company_user", company_user);
        params.put("card_name", card_name);
        params.put("card_num", card_num);
        params.put("issue_bank_name", issue_bank_name);
        params.put("issue_bank_address", issue_bank_address);
        params.put("memo", memo);
        String paramStr = company_id + bank_id + company_order_num + amount + card_num + card_name + company_user + issue_bank_name + issue_bank_address + memo;
        params.put("key", signDataStr(paramStr));

        System.out.println("参数列表：" + "company_id=" + company_id + "\n"
                + "bank_id=" + bank_id + "\n"
                + "account=" + amount + "\n"
                + "company_order_num=" + company_order_num + "\n"
                + "company_user=" + company_user + "\n"
                + "card_name=" + card_name + "\n"
                + "card_num=" + card_num + "\n"
                + "issue_bank_name=" + issue_bank_name + "\n"
                + "issue_bank_address=" + issue_bank_address + "\n"
                + "memo=" + memo + "\n"
                + "key=" + signDataStr(paramStr) + "\n"
        );

        String result = HttpClientUtils.httpPost(url, params);
        System.out.println("聚宝盆提现返回结果：" + result);
        return (Map) JSON.parse(result);
    }

    static String signDataStr(String paramStr) throws Exception {
        String signData = MD5Utils.getMd5(MD5Utils.getMd5(JbpPayConfig.KEY) + paramStr);
        System.out.println("请求数据：" + paramStr + "signature=" + signData);
        return signData;
    }

    /**
     * 异步请求数据验签
     *
     * @param retMap
     * @return
     */
    public static boolean verferSignData(Map<String, String> retMap, String type) {
        String signatureStr = "";
        String key = "";
        if (type.equals("addTransfer")) {
            String pay_time = retMap.get("pay_time");
            String bank_id = retMap.get("bank_id");
            String amount = retMap.get("account");
            String company_order_num = retMap.get("company_order_num");
            String mownecum_order_num = retMap.get("mownecum_order_num");
            String pay_card_num = retMap.get("pay_card_num");
            String pay_card_name = retMap.get("pay_card_name");
            String channel = retMap.get("channel");
            String area = retMap.get("area");
            String fee = retMap.get("fee");
            String transaction_charge = retMap.get("transaction_charge");
            String deposit_mode = retMap.get("deposit_mode");
            String base_info = retMap.get("base_info");
            String operating_time = retMap.get("operating_time");
            key = retMap.get("key");
            if(StringUtils.isNotBlank(pay_time)){
                signatureStr += pay_time;
            }
            if(StringUtils.isNotBlank(bank_id)){
                signatureStr += bank_id;
            }
            if(StringUtils.isNotBlank(amount)){
                signatureStr += amount;
            }
            if(StringUtils.isNotBlank(company_order_num)){
                signatureStr += company_order_num;
            }
            if(StringUtils.isNotBlank(mownecum_order_num)){
                signatureStr += mownecum_order_num;
            }
            if(StringUtils.isNotBlank(pay_card_num)){
                signatureStr += pay_card_num;
            }
            if(StringUtils.isNotBlank(pay_card_name)){
                signatureStr += pay_card_name;
            }
            if(StringUtils.isNotBlank(channel)){
                signatureStr += channel;
            }
            if(StringUtils.isNotBlank(area)){
                signatureStr += area;
            }
            if(StringUtils.isNotBlank(fee)){
                signatureStr += fee;
            }
            if(StringUtils.isNotBlank(transaction_charge)){
                signatureStr += transaction_charge;
            }
            if(StringUtils.isNotBlank(deposit_mode)){
                signatureStr += deposit_mode;
            }

//            signatureStr = pay_time + bank_id + account + company_order_num + mownecum_order_num + pay_card_num + pay_card_name + channel + area + fee + transaction_charge + deposit_mode;
        } else if ("withdrawalResult".equals(type)) {
            String status = retMap.get("status");
            String mownecum_order_num = retMap.get("mownecum_order_num");
            String company_order_num = retMap.get("company_order_num");
            String amount = retMap.get("account");
            String detail = retMap.get("detail");
            String exact_transaction_charge = retMap.get("exact_transaction_charge");
            key = retMap.get("key");

            if(StringUtils.isNotBlank(mownecum_order_num)){
                signatureStr += mownecum_order_num;
            }
            if(StringUtils.isNotBlank(company_order_num)){
                signatureStr += company_order_num;
            }
            if(StringUtils.isNotBlank(status)){
                signatureStr += status;
            }
            if(StringUtils.isNotBlank(amount)){
                signatureStr += amount;
            }
            if(StringUtils.isNotBlank(exact_transaction_charge)){
                signatureStr += exact_transaction_charge;
            }
//            signatureStr = mownecum_order_num + company_order_num + status + account + exact_transaction_charge;
        } else if ("requestWithdrawApproveInformation".equals(type)) {
            String status = retMap.get("status");
            String mownecum_order_num = retMap.get("mownecum_order_num");
            String company_order_num = retMap.get("company_order_num");
            String company_user = retMap.get("company_user");
            String amount = retMap.get("account");
            String card_name = retMap.get("card_name");
            String card_num = retMap.get("card_num");
            key = retMap.get("key");

            if(StringUtils.isNotBlank(company_order_num)){
                signatureStr += company_order_num;
            }
            if(StringUtils.isNotBlank(mownecum_order_num)){
                signatureStr += mownecum_order_num;
            }
            if(StringUtils.isNotBlank(amount)){
                signatureStr += amount;
            }
            if(StringUtils.isNotBlank(card_num)){
                signatureStr += card_num;
            }
            if(StringUtils.isNotBlank(card_name)){
                signatureStr += card_name;
            }
            if(StringUtils.isNotBlank(company_user)){
                signatureStr += company_user;
            }
//            signatureStr = company_order_num + mownecum_order_num + account + card_num + card_name + company_user;
        } else if ("exceptionWithdrawApply".equals(type)) {
            String exception_order_num = retMap.get("exception_order_num");
            String company_id = retMap.get("company_id");
            String exact_payment_bank = retMap.get("exact_payment_bank");
            String pay_card_name = retMap.get("pay_card_name");
            String pay_card_num = retMap.get("pay_card_num");
            String receiving_bank = retMap.get("receiving_bank");
            String receiving_account_name = retMap.get("receiving_account_name");
            String channel = retMap.get("channel");
            String note = retMap.get("note");
            String area = retMap.get("area");
            String exact_time = retMap.get("exact_time");
            String amount = retMap.get("account");
            String fee = retMap.get("fee");
            String transaction_charge = retMap.get("transaction_charge");
            String base_info = retMap.get("base_info");
            String operating_time = retMap.get("operating_time");
            key = retMap.get("key");
            String feeStr = StringUtils.isBlank(fee) ? "0.00" : fee;

            if(StringUtils.isNotBlank(exception_order_num)){
                signatureStr += exception_order_num;
            }
            if(StringUtils.isNotBlank(company_id)){
                signatureStr += company_id;
            }
            if(StringUtils.isNotBlank(exact_payment_bank)){
                signatureStr += exact_payment_bank;
            }
            if(StringUtils.isNotBlank(pay_card_name)){
                signatureStr += pay_card_name;
            }
            if(StringUtils.isNotBlank(pay_card_num)){
                signatureStr += pay_card_num;
            }
            if(StringUtils.isNotBlank(receiving_bank)){
                signatureStr += receiving_bank;
            }
            if(StringUtils.isNotBlank(receiving_account_name)){
                signatureStr += receiving_account_name;
            }
            if(StringUtils.isNotBlank(channel)){
                signatureStr += channel;
            }
            if(StringUtils.isNotBlank(note)){
                signatureStr += note;
            }
            if(StringUtils.isNotBlank(area)){
                signatureStr += area;
            }
            if(StringUtils.isNotBlank(exact_time)){
                signatureStr += exact_time;
            }
            if(StringUtils.isNotBlank(amount)){
                signatureStr += amount;
            }
            if(StringUtils.isNotBlank(feeStr)){
                signatureStr += feeStr;
            }
            if(StringUtils.isNotBlank(transaction_charge)){
                signatureStr += transaction_charge;
            }
//            signatureStr = exception_order_num + company_id + exact_payment_bank + pay_card_name + pay_card_num + receiving_bank + receiving_account_name + channel + note + area + exact_time + account + feeStr + transaction_charge;
        }
        log.info("聚宝盆验签数据：" + signatureStr);
        log.info("聚宝盆数字签名：" + key);
        String signData = MD5Utils.getMd5(MD5Utils.getMd5(JbpPayConfig.KEY) + signatureStr);
        log.info("本地加密结果："+signData);
        if (key.equals(signData)) {
            log.info("聚宝盆验签通过");
            return true;
        }
        log.info("聚宝盆验签不通过");
        return false;
    }

    /**
     * 获取支持银行卡列表
     *
     * @return
     */
    public static List<Map<String, Object>> getBankList() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> data1 = new HashMap<>();
        Map<String, Object> data2 = new HashMap<>();
        Map<String, Object> data3 = new HashMap<>();
        Map<String, Object> data4 = new HashMap<>();
        Map<String, Object> data5 = new HashMap<>();
        Map<String, Object> data6 = new HashMap<>();
        Map<String, Object> data7 = new HashMap<>();
        Map<String, Object> data8 = new HashMap<>();
        Map<String, Object> data9 = new HashMap<>();
        Map<String, Object> data10 = new HashMap<>();
        Map<String, Object> data11 = new HashMap<>();
        Map<String, Object> data12 = new HashMap<>();
        Map<String, Object> data13 = new HashMap<>();
        Map<String, Object> data14 = new HashMap<>();
        Map<String, Object> data15 = new HashMap<>();
        data1.put("id", "1");
        data1.put("bankName", "工商银行");
        data1.put("bankCode", "ICBC");
        data2.put("id", "2");
        data2.put("bankName", "招商银行");
        data2.put("bankCode", "CMB");
        data3.put("id", "3");
        data3.put("bankName", "建设银行");
        data3.put("bankCode", "CCB");
        data4.put("id", "4");
        data4.put("bankName", "农业银行");
        data4.put("bankCode", "ABC");
        data5.put("id", "5");
        data5.put("bankName", "中国银行");
        data5.put("bankCode", "BOC");
        data6.put("id", "6");
        data6.put("bankName", "交通银行");
        data6.put("bankCode", "BCM");
        data7.put("id", "7");
        data7.put("bankName", "民生银行");
        data7.put("bankCode", "CMBC");
        data8.put("id", "8");
        data8.put("bankName", "中信银行");
        data8.put("bankCode", "ECC");
        data9.put("id", "9");
        data9.put("bankName", "浦发银行");
        data9.put("bankCode", "SPDB");
        data10.put("id", "10");
        data10.put("bankName", "邮政储汇");
        data10.put("bankCode", "PSBC");
        data11.put("id", "11");
        data11.put("bankName", "光大银行");
        data11.put("bankCode", "CEB");
        data12.put("id", "12");
        data12.put("bankName", "平安银行");
        data12.put("bankCode", "PINGAN");
        data13.put("id", "13");
        data13.put("bankName", "广发银行");
        data13.put("bankCode", "CGB");
        data14.put("id", "14");
        data14.put("bankName", "华夏银行");
        data14.put("bankCode", "HXB");
        data15.put("id", "15");
        data15.put("bankName", "兴业银行");
        data15.put("bankCode", "CIB");
        list.add(data1);
        list.add(data2);
        list.add(data3);
        list.add(data4);
        list.add(data5);
        list.add(data6);
        list.add(data7);
        list.add(data8);
        list.add(data9);
        list.add(data10);
        list.add(data11);
        list.add(data12);
        list.add(data13);
        list.add(data14);
        list.add(data15);
        return list;
    }


    public static String outIdToName(int id) {
        switch (id) {
            case 1:
                return "工商银行";
            case 2:
                return "招商银行";
            case 3:
                return "建设银行";
            case 4:
                return "农业银行";
            case 5:
                return "中国银行";
            case 6:
                return "交通银行";
            case 7:
                return "民生银行";
            case 8:
                return "中信银行";
            case 9:
                return "浦发银行";
            case 10:
                return "邮政储汇";
            case 11:
                return "光大银行";
            case 12:
                return "平安银行";
            case 13:
                return "广发银行";
            case 14:
                return "华夏银行";
            case 15:
                return "兴业银行";
            default:
                return "";
        }
    }

    public static String outIdToCode(int id) {
        switch (id) {
            case 1:
                return "ICBC";
            case 2:
                return "CMB";
            case 3:
                return "CCB";
            case 4:
                return "ABC";
            case 5:
                return "BOC";
            case 6:
                return "BCM";
            case 7:
                return "CMBC";
            case 8:
                return "ECC";
            case 9:
                return "SPDB";
            case 10:
                return "PSBC";
            case 11:
                return "CEB";
            case 12:
                return "PINGAN";
            case 13:
                return "CGB";
            case 14:
                return "HXB";
            case 15:
                return "CIB";
            default:
                return "";
        }
    }

}
